﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.ComponentModel;
using System.IO;
using System.Reflection;
using System.Xml.Serialization;
using System.Linq.Expressions;

namespace Sortable
{
    [DataObject]
    public class PersonDataSource
    {
        private static List<Person> AllPerson;

        static PersonDataSource()
        {
            using (Stream stream = Assembly.GetExecutingAssembly().GetManifestResourceStream("Sortable.People.xml"))
            {
                XmlSerializer serializer = new XmlSerializer(typeof(Person[]));
                AllPerson = new List<Person>((Person[])serializer.Deserialize(stream));
            }
        }

        [DataObjectMethod(DataObjectMethodType.Select)]
        public static IList<Person> Select() { return Select(-1, 0, string.Empty); }
        public static IList<Person> Select(string SortExpression) { return Select(-1, 0, SortExpression); }
        public static IList<Person> Select(int maximumRows, int startRowIndex) { return Select(maximumRows, startRowIndex, string.Empty); }
        public static IList<Person> Select(int maximumRows, int startRowIndex, string sortExpression)
        {
            IEnumerable<Person> ret = AllPerson;
            if (!string.IsNullOrEmpty(sortExpression))
            {
                bool desc = sortExpression.EndsWith(" DESC");
                if (desc) sortExpression = sortExpression.Substring(0, sortExpression.Length - 5);
                Func<Person, object> sel = null;
                switch (sortExpression)
                {
                    case "Title":
                        sel = p => p.Title;
                        break;
                    case "FirstName":
                        sel = p => p.FirstName;
                        break;
                    case "LastName":
                        sel = p => p.LastName;
                        break;
                }

                if (sel != null)
                {
                    if (desc) ret = ret.OrderByDescending(sel);
                    else ret = ret.OrderBy(sel);
                }
            }
            if (startRowIndex != 0) ret = ret.Skip(startRowIndex);
            if (maximumRows != -1) ret = ret.Take(maximumRows);
            return ret.ToList();
        }

        [DataObjectMethod(DataObjectMethodType.Select)]
        public static int SelectCount() 
        {
            return AllPerson.Count;
        }
    }
}